
var Bomb = GameObject.extend({
	delay: 60, // time in FPS it takes the bomb to explode
	radius: 2, // explosion default reach
	reach: null, // has all 4 sides reach
	planter: null, // player, who planted the bomb
	timer: 0, // this is used to calculate explosion delay
	reach: {left: null, upper: null, right: null, lower: null},
	
	animationDuration: 20,
	explosionTimer: 0,
	
	init: function(x_abs, y_abs, planter) {
		this.setPos(x_abs, y_abs);
		this.planter = planter;
		this.reach.left = this.radius;
		this.reach.upper = this.radius;
		this.reach.right = this.radius;
		this.reach.lower = this.radius;
	},
	explode: function() {
		this.planter.bombExploded();
		// removes bomb
		bombs[bombs.indexOf(this)] = undefined;
		// explodes walls
		toExplode = [];
		if (isExplodable(pos = this.getShiftedLeftPos())) {
			toExplode.push(pos);
		}
		if (isExplodable(pos = this.getShiftedUpPos())) {
			toExplode.push(pos);
		}
		if (isExplodable(pos = this.getShiftedRightPos())) {
			toExplode.push(pos);
		}
		if (isExplodable(pos = this.getShiftedDownPos())) {
			toExplode.push(pos);
		}
		explodeBlocks(toExplode);
		
		this.nearbyBombsExplosion();
		
		// player lives calculations
		for (var i = 0; i < players.length; i++) {
			if (this.posInReach(players[i].getPosX(), players[i].getPosY())) {
				players[i].removeLife();
				this.planter.addKills();
			}
		}
	},
	nearbyBombsExplosion: function() {
		nearbyBombs = this.getNearbyBombs();
		for (var i = 0; i < nearbyBombs.length; i ++) {
			nearbyBombs[i].explode();
		}
	},
	getNearbyBombs: function() {
		nearbyBombs = [];
		pos = this.getShiftedLeftPos();
		foundBomb = getItemByPos(bombs, pos.x, pos.y);
		if (foundBomb != -1) {
			nearbyBombs.push(foundBomb);
		}
		pos = this.getShiftedUpPos();
		foundBomb = getItemByPos(bombs, pos.x, pos.y);
		if (foundBomb != -1) {
			nearbyBombs.push(foundBomb);
		}
		pos = this.getShiftedRightPos();
		foundBomb = getItemByPos(bombs, pos.x, pos.y);
		if (foundBomb != -1) {
			nearbyBombs.push(foundBomb);
		}
		pos = this.getShiftedDownPos();
		foundBomb = getItemByPos(bombs, pos.x, pos.y);
		if (foundBomb != -1) {
			nearbyBombs.push(foundBomb);
		}
		return nearbyBombs;
	},
	changeReaches: function() {
		x = this.getPosX();
		y = this.getPosY();
		for (var l = 1; l <= this.reach.left; l ++) {
			if (x - l < 0) {
				this.reach.left = l - 1;
				break;
			}
			else if (!isPlaceFree(x - l, y)) {
				this.reach.left = l;
				break;
			}
		}
		for (var u = 1; u <= this.reach.upper; u ++) {
			if (y - u < 0) {
				this.reach.upper = u - 1;
				break;
			}
			else if (!isPlaceFree(x, y - u)) {
				this.reach.upper = u;
				break;
			}
		}
		max = level.map.length;
		for (var r = 1; r <= this.reach.right; r ++) {
			if (x + r >= max) {
				this.reach.right = r - 1;
				break;
			}
			else if (!isPlaceFree(x + r, y)) {
				this.reach.right = r;
				break;
			}
		}
		max = level.map[0].length;
		for (var d = 1; d <= this.reach.lower; d ++) {
			if (y + d >= max) {
				this.reach.lower = d - 1;
				break;
			}
			else if (!isPlaceFree(x, y + d)) {
				this.reach.lower = d;
				break;
			}
		}
	},
	posInReach: function(x, y) {
		bombX = this.getPosX();
		bombY = this.getPosY();
		if (bombX - this.reach.left <= x && bombY == y && bombX + this.reach.right >= x) {
			return true;
		}
		if (bombY - this.reach.upper <= y && bombX == x && bombY + this.reach.lower >= y) {
			return true;
		}
		return false;
	},
	update: function() {
		this.timer ++;
		if (this.timer >= this.delay) {
			this.explode();
		}
	},
	assignKey: function(key) {
		this.assignedKey = key;
	},
	getShiftedUpPos: function() {
		return {
			x: this.getPosX(),
			y: this.getPosY() - this.reach.upper
		};
	},
	getShiftedDownPos: function() {
		return {
			x: this.getPosX(),
			y: this.getPosY() + this.reach.lower
		};
	},
	getShiftedRightPos: function() {
		return {
			x: this.getPosX() + this.reach.right,
			y: this.getPosY()
		};
	},
	getShiftedLeftPos: function() {
		return {
			x: this.getPosX() - this.reach.left,
			y: this.getPosY()
		};
	},
	explosionAnimation: function() {
		this.changeReaches();

		
		
		this.explosionTimer ++;
		if (this.explosionTimer < 4) {
			this.drawExplosion(maxGrid * this.explosionTimer, maxGrid * 2, maxGrid, this.x - offSet, this.y - offSet, maxGrid);
		}
		else {
			imagesPerGrid = 2;
			timerLeft = this.animationDuration - this.explosionTimer;
			for (var i = 1; i <= this.radius; i ++) {
				if (i <= this.reach.left) {
					for (var t = 1; t <= imagesPerGrid; t ++) {
						this.drawExplosion(0, maxGrid * 2, maxGrid, this.x - offSet - (i * grid / timerLeft / t), this.y - offSet, maxGrid);
					}
				}
				if (i <= this.reach.upper) {
					for (var t = 1; t <= imagesPerGrid; t ++) {
						this.drawExplosion(0, maxGrid * 2, maxGrid, this.x - offSet, this.y - offSet - (i * grid / timerLeft / t), maxGrid);
					}
				}
				if (i <= this.reach.right) {
					for (var t = 1; t <= imagesPerGrid; t ++) {
						this.drawExplosion(0, maxGrid * 2, maxGrid, this.x - offSet + (i * grid / timerLeft / t), this.y - offSet, maxGrid);
					}
				}
				if (i <= this.reach.lower) {
					for (var t = 1; t <= imagesPerGrid; t ++) {
						this.drawExplosion(0, maxGrid * 2, maxGrid, this.x - offSet, this.y + (i * grid / timerLeft / t) - offSet, maxGrid);
					}
				}
			}
		}
	},
	drawExplosion: function(xsrc, ysrc, cutSize, x, y, scaledSize) {
		try {
			ctx.drawImage(images["spritesheet1"], xsrc, ysrc, cutSize, cutSize, x, y, scaledSize, scaledSize);
		} catch(e) {
			alert(e);
		}
	},
	draw: function() {
		try {
			if (this.timer < this.delay - this.animationDuration) {
				ctx.drawImage(images["spritesheet1"], 0, maxGrid * 2, maxGrid, maxGrid, this.x - offSet, this.y- offSet, maxGrid, maxGrid);
			}
			else {
				this.explosionAnimation();
			}
		} catch(e) {
			alert(e);
		}
	}
});